home *** CD-ROM | disk | FTP | other *** search
- /****************************************************************************
- *
- * $Source: /unixb/home/unixlib/source/unixlib37/src/signal/c/RCS/coredump,v $
- * $Date: 1996/11/06 22:01:42 $
- * $Revision: 1.2 $
- * $State: Rel $
- * $Author: unixlib $
- *
- * $Log: coredump,v $
- * Revision 1.2 1996/11/06 22:01:42 unixlib
- * Yet more changes by NB, PB and SC.
- *
- * Revision 1.1 1996/10/30 21:57:16 unixlib
- * Initial revision
- *
- ***************************************************************************/
-
- static const char rcs_id[] = "$Id: coredump,v 1.2 1996/11/06 22:01:42 unixlib Rel $";
-
- /* signal.c.coredump. Write out core dump/termination diagnostic
- information for a process. */
-
- /* This source file should be compiled with stack checking turned off.
- Ideally they should be re-written in assembler. */
-
- #include <unixlib/sigstate.h>
- #include <sys/unix.h>
- #include <sys/syslib.h>
- #include <sys/swis.h>
- #include <sys/os.h>
-
- #pragma no_check_stack
-
- static char *__rname[16] =
- {
- "a1", "a2", "a3", "a4",
- "v1", "v2", "v3", "v4", "v5", "v6",
- "sl", "fp", "ip", "sp", "lr", "pc"
- };
-
- struct trace
- {
- unsigned int *fp;
- unsigned int *sp;
- unsigned int *lr;
- unsigned int *pc;
- };
-
-
- void
- __backtrace (register unsigned int *fp)
- {
- struct trace *f;
- unsigned int *pc;
- int i;
- char *n;
- int features;
- int regs[10];
- register struct env *e;
-
- /* Remove environment handlers. */
- e = __Oenv;
- for (i = 0; i < 13; i++)
- if (i != 11) /* Do not remove exit handler. */
- __wrenv (i, e->h + i);
-
- os_print ("\rstack backtrace:\r\n\n");
-
- regs[0] = 0;
- /* If SWI returns an error then assume unknown and thus not StrongARM. */
- if (os_swi (OS_PlatformFeatures, regs))
- features = 0;
- else
- features = regs[0];
-
-
- while (fp)
- {
- f = (struct trace *) (fp - 3);
- pc = (unsigned int *) ((unsigned int) f->pc & 0x03fffffcU);
- /* Bit 3 of features set => stored PC is PC+8 rather than PC+12. */
- if (features & 0x08)
- pc++;
- if ((unsigned int) (f->fp) & 0x80000000U)
- {
- os_print ("\r\n\n pc: ");
- os_prhex ((int) pc);
- os_print (" sp: ");
- os_prhex ((int) f->sp);
- n = "?"; /* SJC */
- for (i = -3; i > -7; i--)
- if ((pc[i] & 0xffffff00U) == 0xff000000U)
- {
- n = (char *) (pc + i) - (pc[i] & 0xffU);
- break;
- }
- os_print (" ");
- os_print (n); /* SJC */
- os_print ("()\r\n");
- fp++;
- os_print ("\r\nRegister dump:\r\n");
- for (i = 0; i < 16; i++)
- {
- if (!(i & 3))
- os_print ("\r\n ");
- os_print (__rname[i]);
- os_print (": ");
- os_prhex (fp[i]);
- os_print (" ");
- }
- os_print ("\r\n\n\n");
- fp = (unsigned int *) ((unsigned int) (f->fp) & ~0x80000000U);
- }
- else
- {
- n = "?";
- for (i = -3; i > -7; i--)
- if ((pc[i] & 0xffffff00U) == 0xff000000U)
- {
- n = (char *) (pc + i) - (pc[i] & 0xffU);
- break;
- }
- os_print (" pc: ");
- os_prhex ((int) pc);
- os_print (" sp: ");
- os_prhex ((int) f->sp);
- os_print (" ");
- os_print (n);
- os_print ("()\r\n");
- fp = f->fp;
- }
- }
- os_print ("\r\n");
-
- /* reinstall handlers */
- e = __Cenv;
- for (i = 0; i < 13; i++)
- __wrenv (i, e->h + i);
- }
-
- int
- __write_corefile (int signo, int sigcode, int sigerror)
- {
- os_print ("\n\rFatal signal received: ");
- os_print (sys_siglist[signo]);
- #if 0
- os_print ("\n\rsignal code = 0x");
- os_prhex (sigcode);
- os_print (" signal error = 0x");
- os_prhex (sigerror);
- #else
- sigcode = sigcode;
- sigerror = sigerror;
- #endif
- os_print ("\n\rA core dump will now follow ...\n\r");
-
- /* Do a core-dump. */
- __core ();
- return 1;
- }
-
- void
- __write_termination (int signo, int sigcode, int sigerror)
- {
- os_print ("\n\rTermination signal received: ");
- os_print (sys_siglist[signo]);
- os_print ("\n\r");
- sigcode = sigcode;
- sigerror = sigerror;
- }
-